package com.hubu.utils;
import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
public class FileUtils {
    public static void copyFileByLine(String srcPath,String destPath){
        File srcFile=new File(srcPath);
        //检验源文件
        if(!srcFile.exists()||!srcFile.isFile()||!srcFile.canRead()){
            throw new RuntimeException("目标文件"+srcFile+"无法操作");
        }
        File destFile=new File(destPath);
        //如果父级目录不存在，尝试创建出来
        String parent = destFile.getParent();
        File parentFile=new File(parent);
        if(!parentFile.exists()){
            parentFile.mkdirs();
        }

        //判断当前目录是否合法
        if(destFile.exists()&&destFile.isDirectory()){
            throw new RuntimeException("拷贝位置是目录,无法拷贝");
        }
        copyFileByLine(srcFile,destFile);
    }
    public static void copyFile(String srcPath,String destPath){
        File srcFile=new File(srcPath);
        //检验源文件
        if(!srcFile.exists()||!srcFile.isFile()||!srcFile.canRead()){
            throw new RuntimeException("目标文件"+srcFile+"无法操作");
        }
        File destFile=new File(destPath);
        //如果父级目录不存在，尝试创建出来
        String parent = destFile.getParent();
        File parentFile=new File(parent);
        if(!parentFile.exists()){
            parentFile.mkdirs();
        }
        //判断当前目录是否合法
        if(destFile.exists()&&destFile.isDirectory()){
            throw new RuntimeException("拷贝位置是目录,无法拷贝");
        }
        copyFile(srcFile,destFile);
    }
    private static void copyFile(File srcFile,File destFile) {
        String parent = destFile.getParent();
        File parentFile=new File(parent);
        if(!parentFile.exists()){
            parentFile.mkdirs();
        }
        //判断当前目录是否合法
        if(destFile.exists()&&destFile.isDirectory()){
            throw new RuntimeException("拷贝位置是目录,无法拷贝");
        }
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        byte[] buffer = new byte[ 1024 * 1024];
        System.out.println("parent="+destFile.getParent());
        try {
            fileInputStream = new FileInputStream(srcFile);
            fileOutputStream = new FileOutputStream(destFile);
            int read = -1;
            while (true) {
                try {
                    read = fileInputStream.read(buffer);
                    //读取完毕
                    if (read == -1) {
                        break;
                    }
                    try {
                        fileOutputStream.write(buffer, 0, read);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static  void copyDirectory(String srcPath,String destPath,List<String> predicts){

        FileFilter fileFilter = createFileFilter(predicts);


        File srcFile=new File(srcPath);
        //检验源文件
        if(!srcFile.exists()||srcFile.isFile()||!srcFile.canRead()){
            throw new RuntimeException("目标文件"+srcFile+"无法操作");
        }
        int index = destPath.indexOf(srcPath);
        if(index!=-1){
            System.out.println("目标目录包含源目录");
        }
        File destFile=new File(destPath);



        destFile.mkdirs();

        if(destFile.exists()&&destFile.isFile()){
            throw new RuntimeException("拷贝位置是文件,无法拷贝");
        }
        copyDirectory(srcFile,destFile,fileFilter,destPath);
    }

    private static void copyDirectory(File srcFile,File destFile,FileFilter fileFilter,String destPath){
        File[] files= fileFilter==null?srcFile.listFiles():srcFile.listFiles(fileFilter);
        if (files != null && files.length > 0) {
            for (File item : files) {
                if (item.isDirectory()) {
                    if(item.getAbsolutePath().equals(destPath)){
                        continue;
                    }
                    //如果当前文件是目录，先将目录创建出来
                    File currentDestFile = new File(destFile, item.getName());

                    if (!currentDestFile.exists()) {
                        currentDestFile.mkdirs();
                    }
                    copyDirectory(item, currentDestFile,destPath);
                } else if (item.isFile()) {
                    copyFile(item, new File(destFile, item.getName()));
                }
            }
        }
    }
    private static void copyDirectory(File srcFile,File destFile,String destPath) {
        File[] files = srcFile.listFiles();
        if (files != null && files.length > 0) {
            for (File item : files) {
                if (item.isDirectory()) {
                    if(item.getAbsolutePath().equals(destPath)){
                        continue;
                    }
                    //如果当前文件是目录，先将目录创建出来
                    File currentDestFile = new File(destFile, item.getName());

                    if (!currentDestFile.exists()) {
                        currentDestFile.mkdirs();
                    }
                    copyDirectory(item, currentDestFile,destPath);
                } else if (item.isFile()) {
                    copyFile(item, new File(destFile, item.getName()));
                }
            }
        }
    }
    public static void copyFileByLine(File srcFile,File destFile) {
        String parent = destFile.getParent();
        File parentFile = new File(parent);
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        }
        //判断当前目录是否合法
        if (destFile.exists() && destFile.isDirectory()) {
            throw new RuntimeException("拷贝位置是目录,无法拷贝");
        }
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        InputStreamReader inputStreamReader = null;
        OutputStreamWriter outputStreamWriter = null;
        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        byte[] buffer = new byte[5 * 1024 * 1024];
        System.out.println("parent=" + destFile.getParent());
        try {
            fileInputStream = new FileInputStream(srcFile);
            fileOutputStream = new FileOutputStream(destFile);

            inputStreamReader = new InputStreamReader(fileInputStream);
            outputStreamWriter = new OutputStreamWriter(fileOutputStream);

            bufferedReader = new BufferedReader(inputStreamReader);
            bufferedWriter = new BufferedWriter(outputStreamWriter);
            String line = null;
            while (true) {
                try {
                    //产生大量的字符串常量
                    line = bufferedReader.readLine();
                    //读取完毕
                    if (line == null) {
                        break;
                    }
                    try {
                        bufferedWriter.write(line);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (bufferedWriter != null) {
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputStreamReader != null) {
                try {
                    inputStreamReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outputStreamWriter != null) {
                try {
                    outputStreamWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    //统计文件的个数
    public static void showFile(String filePath){
        File file=new File(filePath);
        if(file.exists()){
            dfsFile(file);
        }
    }
    public static void dfsFile(File file){
        File[] files = file.listFiles();
        if(files!=null&&files.length>0){
            for(File item:files){
                if(item.isDirectory()){
                    dfsFile(item);
                }
                else if(item.isFile()){
                    System.out.println(item.getAbsolutePath());
                }
            }
        }
    }
    //查找目录下的所有文件
    public static List<String> listAllFilePath(String filePath,FileFilter fileFilter){
        List<String> filePathList=new ArrayList<>();

        File file=new File(filePath);
        if(file.exists()){
            listAllFilePath(file,fileFilter,filePathList);
        }
        return filePathList;
    }
    /**
     *
     * 查询所有匹配该条间的文件
     * @param filePath
     * @param directs
     * @return
     */
    public static List<String> listAllFilePath(String filePath,List<String> directs){
        FileFilter fileFilter = createFileFilter(directs);
        return listAllFilePath(filePath,fileFilter);
    }
    public static  FileFilter createFileFilter(List<String> directs){

        if(directs==null||directs.size()==0){
            return null;
        }
        FileFilter fileFilter=new FileFilter() {
            @Override
            public boolean accept(File file) {
                if(file.isFile()){
                    String fileName=file.getName();
                    for(String item:directs){
                        if(fileName.endsWith(item)){
                            return true;
                        }
                    }
                    return false;
                }
                return true;
            }
        };
        return fileFilter;
    }
    public static void reFileName(String filePath,String newName){
        filePath=windowPattern(filePath);
        File oldFile=new File(filePath);
        if(!oldFile.exists()){
            if(!oldFile.exists()){
                throw new RuntimeException("source file does not exists");
            }
        }
        String parentPath= oldFile.getParent();
        System.out.println(parentPath);

        String newFilePath=parentPath+"\\"+newName;

        File newFile=new File(newFilePath);

        oldFile.renameTo(newFile);
    }
    public static void reFileName(String parentPath,String oldName,String newName){
        parentPath=windowPattern(parentPath);
        System.out.println(parentPath);
        String filePath=parentPath;
        String newFilePath=parentPath;

        if(parentPath.endsWith("\\")){
            filePath=filePath+oldName;
            newFilePath=parentPath+newName;
        }
        else{
            filePath=parentPath+"\\"+oldName;
            newFilePath=parentPath+"\\"+newName;
        }
        File oldFile=new File(filePath);

        File newFile=new File(newFilePath);

        if(!oldFile.exists()){
            throw new RuntimeException("source file does not exists");
        }
        if(newFile.exists()){
            throw new RuntimeException("new file have exists");
        }
        boolean b = oldFile.renameTo(newFile);
    }
    /**
     *
     *
     * 将一个路径转换成为windows标准格式
     * @param srcPath
     * @return
     */
    public static String windowPattern(String srcPath){
        System.out.println(srcPath);
        if(srcPath==null) return null;
        String s = srcPath.replaceAll("/", Matcher.quoteReplacement("\\"));
        return s;
    }
    //查询当前目录下的所有文件
    public static  List<String> listCurrentDirectoryAllFiles(String filePath,List<String> directs){
        //todo
        File file=new File(filePath);
        if(!file.exists()){
            throw new RuntimeException("文件不存在");
        }
        FileFilter fileFilter=null;
        if(directs!=null&&directs.size()>0){
            fileFilter= createFileFilter(directs);
        }
        List<String> filePaths=new ArrayList<>();
        if(fileFilter!=null){
            File[] files = file.listFiles(fileFilter);
            if(files!=null&&files.length>0){
                for(File item:files){
                    if(item.isFile()){
                        filePaths.add(item.getAbsolutePath());
                    }
                }
            }
        }else{
            File[] files = file.listFiles();
            if(files!=null&&files.length>0){
                for(File item:files){
                    if(item.isFile()){
                        filePaths.add(item.getAbsolutePath());
                    }
                }
            }
        }
        return filePaths;

    }
    private  static void  listAllFilePath(File file,FileFilter fileFilter,List<String> filePathList) {
        File[] files = file.listFiles(fileFilter);
        if (files != null && files.length > 0) {
            for (File item : files) {
                if (item != null) {
                    if (item.isFile()) {
                        filePathList.add(item.getAbsolutePath());
                    } else if (item.isDirectory()) {
                        listAllFilePath(item, fileFilter, filePathList);
                    }
                }
            }
        }
    }



    //删除单个文件或者空的文件夹
    public static void deleteFile(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            System.out.println("文件不存在");
        }
        file.deleteOnExit();
    }
    //递归删除整个文件夹里面的所有东西
    public static void deleteAllFile(String filePath){
        File file=new File(filePath);
        if(file.exists()){
            deleteAllFile(file
            );
        }
    }
    private static void deleteAllFile(File file){
        if(file.isDirectory()){
            File[] files = file.listFiles();
            if(files!=null&&files.length>0){
                for(File item:files){
                    deleteAllFile(item);
                }
            }
        }
        file.delete();
    }


    /**
     * 删除给定目录下匹配的所有文件
     * @param filePath
     * @param directs
     */
    public static void deleteFiles(String filePath,List<String> directs){
        FileFilter fileFilter = createFileFilter(directs);
        File file=new File(filePath);
        if(!file.exists()){
            throw new RuntimeException("目录不存在");
        }
        if(file.isFile()){
            throw new RuntimeException("file是一个文件，无法删除");
        }
        deleteFiles(file,fileFilter);
    }
    public static void deleteFiles(File file,FileFilter fileFilter){
        //删除文件
        if(file.isFile()){
            //如果是文件直接删除
            file.deleteOnExit();
        }
        File[] files = file.listFiles(fileFilter);
        if(files!=null&&files.length>0){
            for(File item:files){
                deleteFiles(item,fileFilter);
            }
        }
    }
    public static void writeList(String filePath,List<String> list){
        writeList(filePath,list,Charset.defaultCharset());
    }
    public static void writeList(String filePath,List<String> list,Charset charset){
        if(list==null||list.size()==0){
            throw new RuntimeException("list can not be empty");
        }
        FileOutputStream fileOutputStream=null;
        BufferedWriter bufferedWriter=null;
        OutputStreamWriter outputStreamWriter=null;
        try {
            fileOutputStream=new FileOutputStream(filePath,true);
            outputStreamWriter=new OutputStreamWriter(fileOutputStream);
            bufferedWriter=new BufferedWriter(outputStreamWriter);
            for(String item:list){
                try {
                    bufferedWriter.write(item);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if(fileOutputStream!=null){
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(outputStreamWriter!=null){
                try {
                    outputStreamWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(bufferedWriter!=null){
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void writeString(String filePath, String content,boolean append){
        writeString(filePath,content,Charset.defaultCharset(),append);
    }
    public static void writeString(String filePath, String content, Charset charset,boolean append){
        if(content==null||"".equals(content)){
            throw new RuntimeException("content must not be empty");
        }
        byte[] buffer = content.getBytes(charset);
        writeBytes(filePath,buffer,append);
    }
    public static void writeBytes(String filePath,byte buffer[],boolean append){
        FileOutputStream fileOutputStream=null;
        try {
            fileOutputStream=new FileOutputStream(filePath,append);
            try {
                fileOutputStream.write(buffer,0,buffer.length);
            } catch (IOException e) {
                e.printStackTrace();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if(fileOutputStream!=null){
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /**
     * 读取数据到List集合里面
     * @param filePath
     * @return
     */
    public static List<String> readLines(String filePath){
        List<String> list=new ArrayList<>(1024);
        FileInputStream fileInputStream=null;
        InputStreamReader inputStreamReader=null;
        BufferedReader bufferedReader=null;
        try {
            fileInputStream=new FileInputStream(filePath);
            inputStreamReader=new InputStreamReader(fileInputStream);
            bufferedReader=new BufferedReader(inputStreamReader);
            String line=null;
            while((line=bufferedReader.readLine())!=null){
                list.add(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }
}